import re
import os
import json
import zhipuai
from starcar_command_tool import starcarCommandTool
import zhiputalk

def remove_markdown_code_block(text):
    # 创建正则表达式来匹配代码块标记
    re_pattern = r"```.*?\n"
    text = re.sub(re_pattern, "", text)

    # 去除剩余的代码块结束标记
    re_pattern = r"```"
    text = re.sub(re_pattern, "", text)

    return text

def traverse_dir(dir_path, header_files, source_files):
    for entry in os.scandir(dir_path):
        if entry.is_file():
            # 获取文件扩展名
            extension = os.path.splitext(entry.name)[1]
            # 读取头文件内容
            if extension == ".h":
                with open(entry.path, 'r') as file:
                    content = file.read()
                    filename = os.path.splitext(entry.name)[0]
                    header_files[filename] = content
            # 读取C源文件内容
            elif extension == ".c" or extension==".cpp":
                with open(entry.path, 'r') as file:
                    content = file.read()
                    filename = os.path.splitext(entry.name)[0]
                    source_files[filename] = content
        elif entry.is_dir():
            # 递归遍历子目录
            traverse_dir(entry.path, header_files, source_files)


def translate_prompt():
    
    directory = "./Temp"
    header_files = {}
    source_files = {}

    traverse_dir(directory, header_files, source_files)
    tool = starcarCommandTool()
    robot = zhiputalk.TranslationRobot(api_key="78a5edea9596183887ccf21c33ad7aed.X8rYa9YXlKRdCqNY")
    for filename, header_content in source_files.items():
        # 创建TranslationRobot实例
       
        header_content=header_files[filename]
        source_content=source_files[filename]
       
# 调用translation_Robot方法
        res =robot.translation_Robot(header_content, source_content)
        code=tool.remove_markdown_code_block(res)
        tool.write_text_to_file(code, "./Output/"+filename+".rs")


def translate_by_c2rust_tool():
    tool = starcarCommandTool()
    tool.transpile_c_to_rust("./Temp", "./Output")
    tool.transpile_cpp_to_rust("./Temp", "./Output")
    pass

def move_test_files():
    tool = starcarCommandTool()
    tool.move_files_by_name("./Output/src", "./Output/tests",'./Input/01-Primary/test')
  
    pass
def generate_lib_rs():
    tool = starcarCommandTool()
    tool.generate_lib_rs("./Output/src")
  
    pass

#逐个文件进行cargo test并且修复错误
def process_rust_files(sourcedir, targetdir, testdir):
    # 确保目标目录存在
    if not os.path.exists(targetdir):
        os.makedirs(targetdir)
    if not os.path.exists(testdir):
        os.makedirs(testdir)
    # 遍历源目录中的所有rs文件
    for root, dirs, files in os.walk(sourcedir):
        # 获取相对路径
        rel_path = os.path.relpath(root, sourcedir)
        for file in files:
            if (file.endswith('.c') or file.endswith('.rs') or file.endswith('.cpp'))and file not in ['lib.rs', 'main.rs']:
                file_path = os.path.join(root, file)
                # 读取Rust代码
                with open(file_path, 'r') as f:
                    rust_text = f.read() 
                # 遍历dirs，创建相对路径
                
        # 构建目标目录和测试目录的相对路径
                target_dir_path = os.path.join(targetdir, rel_path)
                test_dir_path = os.path.join(testdir, rel_path)
                if(rel_path=="test"):
                    target_dir_path+="s"
                    test_dir_path+="s"
                    
        
        # 创建目录
                os.makedirs(target_dir_path, exist_ok=True)
                os.makedirs(test_dir_path, exist_ok=True)
                # 检查文件并移动到测试目录
                check_file(file, target_dir_path, test_dir_path,rust_text)
import os
import shutil

def copy_files_with_extensions(source_dir, target_dir):
    """
    Copy files with specific extensions from source directory to target directory.

    Args:
    source_dir (str): The source directory to search for files.
    target_dir (str): The target directory to copy files to.
    extensions (list): A list of file extensions to copy.
    """
    extensions = ['.c', '.h', '.cpp']
# 获取当前工作目录
    current_dir = os.getcwd()
    
    # 判断源目录和目标目录是否是绝对路径
    abs_source_dir = source_dir if os.path.isabs(source_dir) else os.path.join(current_dir, source_dir)
    abs_target_dir = target_dir if os.path.isabs(target_dir) else os.path.join(current_dir, target_dir)

    # 如果目标目录不存在，则创建它
    if not os.path.exists(abs_target_dir):
        os.makedirs(abs_target_dir)

    for root, dirs, files in os.walk(source_dir):
        for file in files:
            if any(file.endswith(ext) for ext in extensions):
                file_path = os.path.join(root, file)
                target_file_path = os.path.join(target_dir, file)
                 # 检查目标目录中是否已存在同名文件
                if not os.path.exists(target_file_path):
                    shutil.copy(file_path, target_file_path)

def check_file(file,prepare_test_dir,test_dir,old_rust_text):
    
    print('process file:' + file)
    robot = zhiputalk.TranslationRobot(api_key="78a5edea9596183887ccf21c33ad7aed.X8rYa9YXlKRdCqNY")
    tool = starcarCommandTool()
    error_count = 100
    iteration_count = 0
    max_iterations = 50
    # 分离文件名和后缀
    file_name, file_extension = os.path.splitext(file)
    file_name = file_name.replace('-', '_')
    new_file_name = file_name + ".rs"
    target_file_path=os.path.join(test_dir, new_file_name)
    src_file_path=os.path.join(prepare_test_dir, new_file_name)
    #语义分析
    result = robot.code_alasy(old_rust_text)
    print("code_alasy:",result )
    # 翻译代码
    result1 = robot.code_translate(result)
    print("translate:",result1 )

    result2 = robot.code_Rust_syntax_fixer(result1)
    print("syntax_fixer:",result2 )
    # 优化代码
    #result = robot.code_optimization_fixer(old_rust_text)
    # 移除Markdown代码块
    rust_style_code = tool.remove_rust_markdown_code_block(result2)
    if rust_style_code is None:
        rust_style_code = result2
    # 将优化后的代码写入源目录
    is_braces_matching=   tool.check_braces_matching(rust_style_code)
    if is_braces_matching==False:
        rust_style_code=robot.fix_function_unexpected_closing_delimiter(rust_style_code)
    tool.write_text_to_file(rust_style_code, src_file_path)
    
    error_count26=1
    functions=tool.split_rust_functions(old_rust_text)
    # 循环直到没有错误或者达到最大迭代次数
    #while error_count > 0 and iteration_count < max_iterations:
    while error_count26 > 0 and iteration_count < max_iterations: 
        error_count26=0   
        # 移动文件到测试目录
        shutil.copy(src_file_path, target_file_path)
        tool.generate_lib_rs(test_dir)
        tool.generate_lib_rs(prepare_test_dir)
        #函数数量缺少的修复
        newfunctions=tool.read_and_split_rust_functions(target_file_path)
        num_new_functions = len(newfunctions)
        num_old_functions = len(functions)
        old_function_name_list=""
        new_function_name_list=""
        rust_text =""
        new_rust_text=""
        # 修复代码错误
        with open(src_file_path, 'r') as file:
            rust_text = file.read()
        with open(target_file_path, 'r') as file:
            new_rust_text = file.read()
        if num_new_functions  < num_old_functions:
            for function in functions:
                function_name=tool.get_function_names(function)
                old_function_name_list+=function_name[0]

            for function in newfunctions:
                function_name=tool.get_function_names(function)  
                new_function_name_list+=function_name[0]  
            lack_of_function_list=robot.find_function_lack_of_src(old_function_name_list,new_function_name_list)
      
            print("函数数量不同，则需要补充完整:"+lack_of_function_list)
            result = robot.fix_lack_of_code(rust_text,lack_of_function_list)
                # 移除Markdown代码块
            code = tool.remove_markdown_code_block(result)
            tool.write_text_to_file(code, src_file_path)
           
        # 运行测试目录下的项目
        result, output = tool.check_rust_project(test_dir)
        previous_error_count= tool.count_errors_in_message(output)
        print("previous_error_count错误数量:", previous_error_count)

        #如果没有错误则跳出
         # 如果没有错误则跳出
        if result and previous_error_count == 0:
            print("没有错误，跳出循环。")
            print(output)  
            break
       
            #分割错误，根据错误的行数修复错误函数
             #循环错误列表，修复错误，直到全部错误修复完整
        errortext=tool.extract_error_details(output)
        # function_start =None
        # new_code=""
        # for key, value in errortext.items():
        #     print(f"Key: {key}, Value: {value}")        
        #     function_text, function_start , function_end =tool.find_function_around_line_in_rust(new_rust_text,int(key))
        #     if(function_start!=None):
        #         fixcode=robot.fix_function(function_text,value)
        #         fixcode=tool.remove_rust_markdown_code_block(fixcode)
        #         new_code=rust_style_code.replace(function_text,fixcode)
        #         tool.write_text_to_file(new_code, target_file_path)
        #     else:
        #         print("找不到函数")
        #         function_text=tool.find_content_around_line_in_rust(new_rust_text,int(key))
        #         fixcode=robot.fix_function(function_text,value)
        #         fixcode=tool.remove_rust_markdown_code_block(fixcode)
        #         new_code=rust_style_code.replace(function_text,fixcode)
        #         tool.write_text_to_file(new_code, target_file_path)
 
        #将修复的代码保存在本地，重新进行编译测试
        # 运行测试目录下的项目
        # result, output = tool.check_rust_project(test_dir)
        error_count = tool.count_errors_in_message(output)
        # print("错误数量:", error_count0)
        print(output)  
        if(error_count>0):   
            errortext=tool.extract_error_details(output)
            for key, value in errortext.items():
                error_filename=tool.extract_rust_file_name(value)
                if(error_filename == None):
                    print("找不到文件名",value)
                    continue
                try:
                    error_target_file_path=os.path.join(test_dir, error_filename)
                    print("执行文件错误修复")    
                    oldcode=""
                    with open(error_target_file_path, 'r') as file:
                        oldcode= file.read()
                    newcode =robot.compiler_error_fixer(value,oldcode)
                    fixcode=tool.remove_markdown_code_block(newcode)
                    tool.write_text_to_file(fixcode, error_target_file_path)
                    result, output = tool.check_rust_project(test_dir)
                    error_count = tool.count_errors_in_message(output)
                except Exception as e:
                    print(e)
                
                
              
        result, output = tool.check_rust_project(test_dir)
        error_count = tool.count_errors_in_message(output)
        print("错误数量:", error_count)
        print(output)  
         # 如果错误数量比上一次的少，则将代码放到待测试目录
        if error_count < previous_error_count:
            shutil.copy(target_file_path, src_file_path)
        
        # 更新迭代次数和错误计数
        iteration_count += 1
        previous_error_count = error_count      
    
    # 如果迭代次数超过最大限制，则停止过程
    if iteration_count >= max_iterations:
        print("达到最大迭代次数，停止过程。需要人工处理")
 

# 设置源目录和目标目录
# source_directory = './Input/01-Primary'
# target_directory = './Temp'

# # 设置要复制的文件扩展名
# tool1 = starcarCommandTool()
#file_path = './Output/src/arraylist.rs'
# # tool1.read_and_split_rust_functions(file_path)
#with open(file_path, 'r') as file:
#    rust_text = file.read()
# robot = zhiputalk.TranslationRobot(api_key="78a5edea9596183887ccf21c33ad7aed.X8rYa9YXlKRdCqNY")
# result=robot.code_optimization_fixer(rust_text)
# code=tool1.remove_markdown_code_block(result)
# tool1.write_text_to_file(code, "./Output/best/arraylist.rs")

#check_file("arraylist.rs","./Output/best","./test_proj/src",rust_text)

# 对每一个rs文件风格化并且进行测试处理
#process_rust_files("./Output/src1", "./Output/best1", "./test_proj/src")
process_rust_files("./Input/01-Primary", "./pending_test", "./Output")
# 调用函数
#将待转换的代码文件复制到对应的缓存目录
#copy_files_with_extensions(source_directory, target_directory)
#调用工具进行转译
#translate_by_c2rust_tool()
#移动测试的文件
#move_test_files()
#生成lib.rs
#generate_lib_rs()

#translate_prompt()
#转译并且将转译后的结果写入到对应的缓存目录同名文件

#编译代码看是否通过
#修复代码
#测试代码是否通过
#修复代码


    #根据行数寻找对应的函数进行修改

# # 示例用法
# header_files = {}
# source_files = {}
# traverse_dir("../Temp", header_files, source_files)